from django.shortcuts import render
from django.db.models import Count, Avg, Max, Min, Sum, F, Q, Case, When, Value
from django.db.models.functions import TruncHour
from django.utils import timezone
from rest_framework import viewsets, status
from rest_framework.decorators import api_view, action
from rest_framework.response import Response
from datetime import datetime, timedelta
from .models import (
    Platform, Keyword, SentimentData, SentimentKeywordRelation,
    MonitorTarget, AlertRule, AlertLog, SystemStatus, DailyStatistics
)
from .serializers import (
    PlatformSerializer, KeywordSerializer, SentimentDataSerializer, SentimentDataBriefSerializer,
    MonitorTargetSerializer, AlertRuleSerializer, AlertLogSerializer,
    SystemStatusSerializer, DailyStatisticsSerializer, HomeStatisticsSerializer
)

# Create your views here.

# 基础 API 视图集
class PlatformViewSet(viewsets.ModelViewSet):
    queryset = Platform.objects.all()
    serializer_class = PlatformSerializer

class KeywordViewSet(viewsets.ModelViewSet):
    queryset = Keyword.objects.all()
    serializer_class = KeywordSerializer

class SentimentDataViewSet(viewsets.ModelViewSet):
    queryset = SentimentData.objects.all()
    serializer_class = SentimentDataSerializer
    
    def get_serializer_class(self):
        if self.action == 'list':
            return SentimentDataBriefSerializer
        return SentimentDataSerializer
    
    def get_queryset(self):
        queryset = SentimentData.objects.all()
        # 时间过滤
        start_date = self.request.query_params.get('start_date')
        end_date = self.request.query_params.get('end_date')
        
        if start_date:
            queryset = queryset.filter(publish_time__gte=start_date)
        if end_date:
            queryset = queryset.filter(publish_time__lte=end_date)
            
        # 情感类型过滤
        sentiment = self.request.query_params.get('sentiment')
        if sentiment:
            queryset = queryset.filter(sentiment_type=sentiment)
        
        # 平台过滤
        platform = self.request.query_params.get('platform')
        if platform:
            queryset = queryset.filter(platform_id=platform)
            
        # 关键词过滤
        keyword = self.request.query_params.get('keyword')
        if keyword:
            queryset = queryset.filter(keywords__word__contains=keyword)
            
        return queryset
    
    @action(detail=False, methods=['get'])
    def latest(self, request):
        """获取最新舆情数据"""
        latest_data = SentimentData.objects.order_by('-publish_time')[:20]
        serializer = SentimentDataBriefSerializer(latest_data, many=True)
        return Response(serializer.data)
    
    @action(detail=False, methods=['get'])
    def hot(self, request):
        """获取热门舆情数据"""
        hot_data = SentimentData.objects.order_by('-heat_value')[:10]
        serializer = SentimentDataBriefSerializer(hot_data, many=True)
        return Response(serializer.data)

class MonitorTargetViewSet(viewsets.ModelViewSet):
    queryset = MonitorTarget.objects.all()
    serializer_class = MonitorTargetSerializer
    
    @action(detail=False, methods=['get'])
    def priority(self, request):
        """获取重点监控目标"""
        targets = MonitorTarget.objects.filter(is_priority=True)
        serializer = MonitorTargetSerializer(targets, many=True)
        return Response(serializer.data)

class AlertRuleViewSet(viewsets.ModelViewSet):
    queryset = AlertRule.objects.all()
    serializer_class = AlertRuleSerializer

class AlertLogViewSet(viewsets.ModelViewSet):
    queryset = AlertLog.objects.all()
    serializer_class = AlertLogSerializer
    
    @action(detail=False, methods=['get'])
    def unhandled(self, request):
        """获取未处理的预警"""
        alerts = AlertLog.objects.filter(is_handled=False)
        serializer = AlertLogSerializer(alerts, many=True)
        return Response(serializer.data)

class SystemStatusViewSet(viewsets.ModelViewSet):
    queryset = SystemStatus.objects.all()
    serializer_class = SystemStatusSerializer

class DailyStatisticsViewSet(viewsets.ModelViewSet):
    queryset = DailyStatistics.objects.all()
    serializer_class = DailyStatisticsSerializer

# 首页数据统计API
@api_view(['GET'])
def home_statistics(request):
    """获取首页统计数据"""
    # print("正在处理首页统计数据请求...")
    
    today = timezone.now().date()
    yesterday = today - timedelta(days=1)
    
    # 今日数据
    today_start = timezone.make_aware(datetime.combine(today, datetime.min.time()))
    today_end = timezone.make_aware(datetime.combine(today, datetime.max.time()))
    
    # 昨日数据
    yesterday_start = timezone.make_aware(datetime.combine(yesterday, datetime.min.time()))
    yesterday_end = timezone.make_aware(datetime.combine(yesterday, datetime.max.time()))
    
    try:
        # 1. 实时数据总览
        # print("计算实时数据总览...")
        today_total = SentimentData.objects.filter(publish_time__range=(today_start, today_end)).count()
        print(f"今日舆情总量: {today_total}")
        
        # 实时新增（最近1小时）
        one_hour_ago = timezone.now() - timedelta(hours=1)
        realtime_increment = SentimentData.objects.filter(publish_time__gte=one_hour_ago).count()
        # print(f"实时新增: {realtime_increment}")
        
        # 当前在线监测平台数
        platform_count = Platform.objects.filter(is_active=True).count()
        # print(f"在线平台数: {platform_count}")
        
        # 2. 情感分布
        # print("计算情感分布...")
        sentiment_stats = SentimentData.objects.filter(
            publish_time__range=(today_start, today_end)
        ).values('sentiment_type').annotate(count=Count('id'))
        
        sentiment_distribution = {
            'positive': 0,
            'neutral': 0,
            'negative': 0
        }
        
        for stat in sentiment_stats:
            if stat['sentiment_type'] == 1:
                sentiment_distribution['positive'] = stat['count']
            elif stat['sentiment_type'] == 0:
                sentiment_distribution['neutral'] = stat['count']
            elif stat['sentiment_type'] == -1:
                sentiment_distribution['negative'] = stat['count']
        
        # 情感趋势变化（近24小时）
        # print("计算情感趋势...")
        last_24h = timezone.now() - timedelta(hours=24)
        sentiment_trend = []
        
        hourly_stats = SentimentData.objects.filter(
            publish_time__gte=last_24h
        ).annotate(
            hour=TruncHour('publish_time')
        ).values('hour', 'sentiment_type').annotate(count=Count('id')).order_by('hour', 'sentiment_type')
        
        hours = {}
        for stat in hourly_stats:
            hour_str = stat['hour'].strftime('%H:00')
            if hour_str not in hours:
                hours[hour_str] = {'hour': hour_str, 'positive': 0, 'neutral': 0, 'negative': 0}
            
            if stat['sentiment_type'] == 1:
                hours[hour_str]['positive'] = stat['count']
            elif stat['sentiment_type'] == 0:
                hours[hour_str]['neutral'] = stat['count']
            elif stat['sentiment_type'] == -1:
                hours[hour_str]['negative'] = stat['count']
        
        sentiment_trend = list(hours.values())
        
        # 3. 热点排名
        # 热门关键词Top10
        hot_keywords = []
        keywords = SentimentKeywordRelation.objects.filter(
            sentiment__publish_time__range=(today_start, today_end)
        ).values('keyword__word').annotate(
            count=Count('sentiment_id'),
            weight=Sum('frequency')
        ).order_by('-weight')[:10]
        
        for keyword in keywords:
            hot_keywords.append({
                'word': keyword['keyword__word'],
                'weight': keyword['weight']
            })
        
        # 热度最高舆情Top5
        hot_sentiments = SentimentData.objects.filter(
            publish_time__range=(today_start, today_end)
        ).order_by('-heat_value')[:5]
        
        hot_sentiments_data = []
        for sentiment in hot_sentiments:
            hot_sentiments_data.append({
                'id': sentiment.id,
                'title': sentiment.title,
                'platform': sentiment.platform.name,
                'heat_value': sentiment.heat_value,
                'sentiment_type': sentiment.sentiment_type,
            })
        
        # 4. 舆情趋势图表
        # 分平台舆情数量对比
        platform_comparison = []
        platform_stats = SentimentData.objects.filter(
            publish_time__range=(today_start, today_end)
        ).values('platform__name').annotate(count=Count('id')).order_by('-count')
        
        for stat in platform_stats:
            platform_comparison.append({
                'platform': stat['platform__name'],
                'count': stat['count']
            })
        
        # 情感值时间分布（散点图数据）
        sentiment_time_distribution = []
        sentiments = SentimentData.objects.filter(
            publish_time__range=(today_start, today_end)
        ).values('id', 'publish_time', 'sentiment_value')
        
        for sentiment in sentiments:
            sentiment_time_distribution.append({
                'id': sentiment['id'],
                'time': sentiment['publish_time'].strftime('%H:%M'),
                'value': sentiment['sentiment_value']
            })
        
        # 5. 关键指标
        # 今日预警次数
        today_alert_count = AlertLog.objects.filter(
            triggered_at__range=(today_start, today_end)
        ).count()
        
        # 昨日预警次数
        yesterday_alert_count = AlertLog.objects.filter(
            triggered_at__range=(yesterday_start, yesterday_end)
        ).count()
        
        # 计算增长率
        if yesterday_alert_count > 0:
            alert_increment = int((today_alert_count - yesterday_alert_count) / yesterday_alert_count * 100)
        else:
            alert_increment = 100 if today_alert_count > 0 else 0
        
        # 重点监控对象
        priority_targets = []
        targets = MonitorTarget.objects.filter(is_priority=True)[:5]
        for target in targets:
            priority_targets.append({
                'id': target.id,
                'name': target.name,
                'type': target.get_type_display(),
                'image': target.image
            })
        
        # 情感极值
        extreme_values = SentimentData.objects.filter(
            publish_time__range=(today_start, today_end)
        ).aggregate(
            max_value=Max('sentiment_value'),
            min_value=Min('sentiment_value')
        )
        
        most_positive = None
        most_negative = None
        
        if extreme_values['max_value'] is not None:
            most_positive_obj = SentimentData.objects.filter(
                publish_time__range=(today_start, today_end),
                sentiment_value=extreme_values['max_value']
            ).first()
            if most_positive_obj:
                most_positive = {
                    'id': most_positive_obj.id,
                    'title': most_positive_obj.title,
                    'value': most_positive_obj.sentiment_value
                }
        
        if extreme_values['min_value'] is not None:
            most_negative_obj = SentimentData.objects.filter(
                publish_time__range=(today_start, today_end),
                sentiment_value=extreme_values['min_value']
            ).first()
            if most_negative_obj:
                most_negative = {
                    'id': most_negative_obj.id,
                    'title': most_negative_obj.title,
                    'value': most_negative_obj.sentiment_value
                }
        
        extreme_sentiment = {
            'most_positive': most_positive,
            'most_negative': most_negative
        }
        
        # 6. 系统状态
        system_services = SystemStatus.objects.all()
        system_status = {
            'crawler': {'status': True, 'response_time': 0},
            'nlp': {'status': True, 'response_time': 0},
            'api': {'status': True, 'response_time': 0}
        }
        
        for service in system_services:
            if service.type in system_status:
                system_status[service.type]['status'] = service.status
                system_status[service.type]['response_time'] = service.response_time
        
        # 组装数据
        # print("组装返回数据...")
        data = {
            'today_total': today_total,
            'realtime_increment': realtime_increment,
            'platform_count': platform_count,
            'sentiment_distribution': sentiment_distribution,
            'sentiment_trend': sentiment_trend,
            'hot_keywords': hot_keywords,
            'hot_sentiments': hot_sentiments_data,
            'platform_comparison': platform_comparison,
            'sentiment_time_distribution': sentiment_time_distribution,
            'alert_count': today_alert_count,
            'alert_increment': alert_increment,
            'priority_targets': priority_targets,
            'extreme_sentiment': extreme_sentiment,
            'system_status': system_status
        }
        
        # print("序列化数据...")
        serializer = HomeStatisticsSerializer(data)
        return Response(serializer.data)
    except Exception as e:
        print(f"处理首页统计数据发生错误: {type(e).__name__}: {e}")
        import traceback
        traceback.print_exc()
        return Response({"error": str(e)}, status=500)
